#ifndef __HC595_H
#define __HC595_H	
	
#include "STC8HX.h"
#include "delay.h"

/*引脚定义*/
#ifndef         HC595_DS
#define 		HC595_DS           P4_4        //SI
#endif

#ifndef         HC595_DS_MODE
#define         HC595_DS_MODE    {P4M1&=~0x10;P4M0|=0x10;}	//推挽输出
#endif

#ifndef         HC595_STCP
#define 		HC595_STCP          P4_3        //RCK
#endif

#ifndef         HC595_STCP_MODE 
#define         HC595_STCP_MODE   {P4M1&=~0x08;P4M0|=0x08;}	//推挽输出
#endif

#ifndef         HC595_SHCP
#define 		HC595_SHCP          P4_2        //SCK
#endif  

#ifndef         HC595_SHCP_MODE
#define         HC595_SHCP_MODE   {P4M1&=~0x04;P4M0|=0x04;}	//推挽输出
#endif

//位码
code uint8 _595_bdata[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};

void hc595_init();                  //595初始化
void hc595_disable();               //595输出禁止
void hc595_enable_nix();            //595使能数码管
void hc595_enable_matrix();         //595使能点阵
void hc595_bit_select(uint8 index); //595发送位选

//========================================================================
// 描述: 595初始化引脚.
// 参数: none.
// 返回: none.
//========================================================================
void hc595_init()
{	
 	HC595_DS_MODE;        //引脚初始化
    HC595_STCP_MODE;
    HC595_SHCP_MODE;

    HC595_DS = 0;
	HC595_STCP = 0;
	HC595_SHCP = 0;
}

//========================================================================
// 描述: 595使能输出.
// 参数: none.
// 返回: none.
//========================================================================
void hc595_out_enable()
{
    HC595_STCP = 0;
    delay10us();delay10us();
    HC595_STCP = 1;
    delay10us();delay10us();
    HC595_STCP = 0;
}

//========================================================================
// 描述: 595发送8位数据.
// 参数: 8位数据.
// 返回: none.
//========================================================================
void hc595_send_byte(uint8 outdata)
{
    uint8 i;
    for(i=0;i<8;i++)  //将8位数据按位发送，先发高字节再发低字节
	{      
        if((outdata&0x80)==0x80)
	    {
            HC595_DS = 1;
        }
	    else
	    {
            HC595_DS = 0;
        }
        HC595_SHCP = 0; //时钟线低电平
        HC595_SHCP = 1; //时钟线高电平
        outdata = outdata<<1;
    }
}

//========================================================================
// 描述: 595发送数组.
// 参数: 数组地址，数据长度.
// 返回: none.
//========================================================================
void hc595_send_multi_byte(uint8 *ddata,uint16 len)
{
    uint16 i;
    for(i=0;i<len;i++)
	{
        hc595_send_byte(ddata[i]);
    }
    hc595_out_enable();
}

//========================================================================
// 描述: 595输出禁止.
// 参数: 数组地址，数据长度.
// 返回: none.
//========================================================================
void hc595_disable()
{
    uint8 buf[2]={0,0};
    hc595_send_multi_byte(buf,2);
}

//========================================================================
// 描述: 595使能数码管.
// 参数: 数组地址，数据长度.
// 返回: none.
//========================================================================
void hc595_enable_nix()
{
    uint8 buf[2]={0,0xff};
    hc595_send_multi_byte(buf,2);
}

//========================================================================
// 描述: 595使能点阵.
// 参数: 数组地址，数据长度.
// 返回: none.
//========================================================================
void hc595_enable_matrix()
{
    uint8 buf[2]={0xff,0};
    hc595_send_multi_byte(buf,2);
}

//========================================================================
// 描述: 595发送位选
// 参数: (0~15)位.
// 返回: none.
//========================================================================
void hc595_bit_select(uint8 index)
{
    //位选
    uint8 buf[2]={0,0};
    if(index>7)
    {
        buf[0]=_595_bdata[index-8];//COM8~COM15 点阵
    }
    else
    {
        buf[1]=_595_bdata[index];//COM0~COM7  数码管
    }
    
    hc595_send_multi_byte(buf,2);
}

#endif
